package org.qpcr.community.relation.terms;

import org.hswebframework.ezorm.core.param.Term;
import org.hswebframework.ezorm.rdb.metadata.RDBColumnMetadata;
import org.hswebframework.ezorm.rdb.metadata.RDBTableMetadata;
import org.hswebframework.ezorm.rdb.metadata.TableOrViewMetadata;
import org.hswebframework.ezorm.rdb.operator.builder.fragments.AbstractTermsFragmentBuilder;
import org.hswebframework.ezorm.rdb.operator.builder.fragments.EmptySqlFragments;
import org.hswebframework.ezorm.rdb.operator.builder.fragments.NativeSql;
import org.hswebframework.ezorm.rdb.operator.builder.fragments.PrepareSqlFragments;
import org.hswebframework.ezorm.rdb.operator.builder.fragments.SqlFragments;
import org.hswebframework.ezorm.rdb.operator.builder.fragments.TermFragmentBuilder;
import org.hswebframework.ezorm.rdb.operator.builder.fragments.term.AbstractTermFragmentBuilder;
import org.qpcr.community.utils.ConverterUtils;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
public class RelatedTerm2Builder extends AbstractTermFragmentBuilder {

    public RelatedTerm2Builder() {
        super("object-related", "按关系信息查询");
    }
    @SuppressWarnings("all")
    public static List<Term> convertTerms(Object value) {
        return ConverterUtils.convertTerms(value);
    }

    @Override
    public SqlFragments createFragments(String columnFullName, RDBColumnMetadata column, Term term) {
        List<Term> terms = convertTerms(term.getValue());
        PrepareSqlFragments sqlFragments = PrepareSqlFragments.of();
        if(term.getOptions().contains("not")){
            sqlFragments.addSql("not");
        }
        sqlFragments
                .addSql("exists(select 1 from ",getTableName("s_object_related",column)," _related where _related.object_id = ", columnFullName);

        RDBTableMetadata metadata = column
                .getOwner()
                .getSchema()
                .getTable("s_object_related")
                .orElseThrow(() -> new UnsupportedOperationException("unsupported s_object_related"));

        SqlFragments where = builder.createTermFragments(metadata, terms);
        if (!where.isEmpty()) {
            sqlFragments.addSql("and")
                    .addFragments(where);
        }
        sqlFragments.addSql(")");
        return sqlFragments;
    }


    static ProductTermBuilder builder = new ProductTermBuilder();

    static class ProductTermBuilder extends AbstractTermsFragmentBuilder<TableOrViewMetadata> {

        @Override
        protected SqlFragments createTermFragments(TableOrViewMetadata parameter, List<Term> terms) {
            return super.createTermFragments(parameter, terms);
        }

        @Override
        protected SqlFragments createTermFragments(TableOrViewMetadata table, Term term) {
            if (term.getValue() instanceof NativeSql) {
                NativeSql sql = ((NativeSql) term.getValue());
                return PrepareSqlFragments.of(sql.getSql(), sql.getParameters());
            }
            return table
                    .getColumn(term.getColumn())
                    .flatMap(column -> table
                            .findFeature(TermFragmentBuilder.createFeatureId(term.getTermType()))
                            .map(termFragment -> termFragment.createFragments(column.getFullName("_related"), column, term)))
                    .orElse(EmptySqlFragments.INSTANCE);
        }
    }
}
